package tech.yixiyun.framework.kuafu.controller.action;


import tech.yixiyun.framework.kuafu.bean.BeanContext;
import tech.yixiyun.framework.kuafu.controller.request.KuafuRequest;
import tech.yixiyun.framework.kuafu.controller.request.param.ParamDefinition;
import tech.yixiyun.framework.kuafu.controller.request.param.ParamValueResolverContext;
import tech.yixiyun.framework.kuafu.controller.request.param.IRequestParamResolver;
import tech.yixiyun.framework.kuafu.controller.response.KuafuResponse;
import tech.yixiyun.framework.kuafu.controller.route.RouteNode;
import tech.yixiyun.framework.kuafu.view.View;
import tech.yixiyun.framework.kuafu.kits.StringKit;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 一个请求对一个Action
 */
public class Action {

    /**
     * 这个请求最终执行的Controller方法
     */
    private RouteNode route;

    /**
     * 执行方法的实例
     */
    private Object instance;

    /**
     * 从url解析的参数，一定要通过getUrlParams()获取，不要直接用它
     */
    private String[] urlParams;
    /**
     * 从请求中解析的参数值，一定要通过getParamValues()获取，不要直接用它
     */
    private Object[] paramValues;

    /**
     * 封装的请求对象
     */
    private KuafuRequest request;

    /**
     * 封装的响应对象
     */
    private KuafuResponse response;

    /**
     * 请求的contentType，不要直接用它，一定要通过getContentType()获取
     */
    private String contentType;



    public Action(RouteNode route, KuafuRequest request, KuafuResponse response) {
        this.route = route;
        this.instance = BeanContext.getBean(route.getMethod().getDeclaringClass());
        this.request = request;
        this.response = response;
    }

    /**
     * 执行这个action
     * @return
     */
    public View execute() throws InvocationTargetException, IllegalAccessException {
        return (View) route.getMethod().invoke(instance, getParamValues());
    }


    public Object[] getParamValues() {
        if (paramValues == null) {

            IRequestParamResolver resolver = ParamValueResolverContext.getResolver(getContentType());
            if (resolver == null) {
                throw new RuntimeException("contentType为" + getContentType() + "的请求没有注册对应ParamValueResolver，无法解析");
            }
            ParamDefinition[] params = getParamDefinitions();
            paramValues = new Object[params.length];
            for (int i = 0; i < params.length; i++) {
                try {
                    paramValues[i] = resolver.resolve(request, params[i]);
                } catch (Exception e) {
                    throw new RuntimeException(route.getPath() + "的参数" + params[i].getName() + "解析失败", e);
                }
            }

        }
        return paramValues;
    }

    public String getContentType() {
        if (this.contentType == null) {
            contentType = request.getContentType();
            if (StringKit.isBlank(contentType)) {
                contentType = "";
            } else {
                String[] types = contentType.split(";");
                contentType = types.length > 0 ? types[0].trim() : "";
            }
        }
        return contentType;
    }


    public Class getControllerClass() {
        return this.route.getMethod().getDeclaringClass();
    }

    public Method getControllerMethod() {
        return this.route.getMethod();
    }

    public ParamDefinition[] getParamDefinitions() {
        return this.route.getParams();
    }

    public RouteNode getRoute() {
        return route;
    }


    public Object getControllerInstance() {
        return instance;
    }


    public KuafuRequest getRequest() {
        return request;
    }


    public KuafuResponse getResponse() {
        return response;
    }

}
